package edu.neumont.pro180._2009_q2;

import java.util.Collection;
import java.util.HashSet;

import edu.neumont.pro180._2009_q2.interfaces.ICommand;
import edu.neumont.pro180._2009_q2.interfaces.IGamePiece;

public class Player {
	protected Collection<IGamePiece> pieces = new HashSet<IGamePiece>();
	protected Board board;
	private IGamePiece selectedPiece = null;
	private ICommand nextMove = null;
	public String name;
	
	/**
	 * Returns the pieces that are currently on the board.
	 * 
	 * @return the pieces that are currently on the board.
	 */
	public Collection<IGamePiece> getActivePieces() {
		Collection<IGamePiece> activePieces = new HashSet<IGamePiece>();
		for (IGamePiece piece : pieces) {
			if (piece.getSquare() != null) {
				activePieces.add(piece);
			}
		}
		return activePieces;
	}

	/**
	 * Returns the pieces that are not currently on the board.
	 * 
	 * @return the pieces that are not currently on the board.
	 */
	public Collection<IGamePiece> getInactivePieces() {
		Collection<IGamePiece> activePieces = new HashSet<IGamePiece>();
		for (IGamePiece piece : pieces) {
			if (piece.getSquare() == null) {
				activePieces.add(piece);
			}
		}
		return activePieces;
	}

	/**
	 * Add an IGamePiece as a piece controlled by this Player.
	 * 
	 * @param piece
	 *            the piece to add to the player's piece collection.
	 */
	public void addGamePiece(IGamePiece piece) {
		this.pieces.add(piece);
	}
	
	public void removeGamePiece(IGamePiece piece) {
		if( piece.getSquare() != null )
			piece.getMove(null).execute();
		pieces.remove(piece);
	}
	
	/**
	 * Get the next move for the player. Returns null if there is not enough
	 * information to give the next move yet. This is kind of a hack in this
	 * class. It's there for the child classes that will be implementing
	 * scripted movement and AI behavior.
	 * 
	 * @return the next Move, or null if not enough information is given to make
	 *         a move.
	 */
	public ICommand getNextMove() {
		ICommand currentMove = this.nextMove;
		if (nextMove != null) {
			selectedPiece = null;
			nextMove = null;
		}
		return currentMove;
	}


	public void setSelectedPiece(IGamePiece piece) {
		if (this.getActivePieces().contains(piece)) {
			this.selectedPiece = piece;
		}
	}
	public IGamePiece getSelectedPiece() {
		return this.selectedPiece;
	}

	public void setPieceDestination(Square square) {
		if (this.selectedPiece != null
				&& this.selectedPiece.getPossibleSquares().contains(square)) {
			nextMove = selectedPiece.getMove(square);
		}
	}

	/**
	 * Sets the board that this player is playing on. Also adds this player to
	 * the board's player collection.
	 * 
	 * @param board
	 *            the board that this player will play on.
	 */
	public void setBoard(Board board) {
		if ((this.board != null) && (board != null)) {
			Board oldBoard = this.board;
			this.board = null;
			oldBoard.removePlayer(this);
		}
		this.board = board;
		if (this.board != null) {
			this.board.addPlayer(this);
		}
	}

	/**
	 * Returns the board this player is playing on.
	 * 
	 * @return the board this player is playing on.
	 */
	public Board getBoard() {
		return this.board;
	}
}
